#coding:utf8
'''python3 code support python2
author's email: chenyan@feling.net

做安卓客户端的时候，用http协议跟服务端通信，传一些字符串
定好了接口，在队友的服务端程序写好之前，自己写个假的服务端测试用

'''
import logging
logging.basicConfig(level=logging.INFO,
                format='%(asctime)s [line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%M:%S',
                )

try:
    from gevent import monkey; monkey.patch_all()
    logging.info('with gevent')
except:
    logging.info('no gevent')

import os, sys
try:
    from http.server import HTTPServer
    from http.server import BaseHTTPRequestHandler
    logging.info('use python3')
except:
    from BaseHTTPServer import HTTPServer
    from BaseHTTPServer import BaseHTTPRequestHandler
    logging.info('use python2')

import urls

class RequestHandler(BaseHTTPRequestHandler):

    funcs_post = {}
    funcs_get = {}

    def do_POST(self):
        if self.path in RequestHandler.funcs_post:
            func = RequestHandler.funcs_post.get(self.path)
            result = func(self)
            if result:
                try:
                    result_byte = bytes(result)
                except:
                    result_byte = bytes(result,encoding='utf8')
                self.send_response(200)
                self.send_header('Content-Length',len(result_byte))
                self.end_headers()
                self.wfile.write(result_byte)
            else:
                self.send_error(500)
        else:
            self.send_error(404)

    def do_GET(self):
        path = self.path.split('?')[0]
        if path in RequestHandler.funcs_get:
            func = RequestHandler.funcs_get.get(path)
            result = func(self)
            if result:
                try:
                    result_byte = bytes(result)
                except:
                    result_byte = bytes(result,encoding='utf8')
                self.send_response(200)
                self.send_header('Content-Length',len(result_byte))
                self.end_headers()
                self.wfile.write(result_byte)
            else:
                self.send_error(500)
        else:
            self.send_error(404)

    def log_message(self, format, *args):
        pass


def POST(uri):
    def decorator(func):
        func.__uri__ = uri
        func.__method__ = 'POST'
        return func
    return decorator

def GET(uri):
    def decorator(func):
        func.__uri__ = uri
        func.__method__ = 'GET'
        return func
    return decorator

def add_url(func):
    if func.__method__ == 'POST':
        RequestHandler.funcs_post[func.__uri__] = func
        logging.info('add url: POST '+func.__uri__)
    if func.__method__ == 'GET':
        RequestHandler.funcs_get[func.__uri__] = func
        logging.info('add url: GET '+func.__uri__)

def add_module(mod):
    for item in dir(mod):
        func = getattr(mod, item)
        if callable(func) and hasattr(func, '__uri__') and hasattr(func, '__method__'):
            add_url(func)

def run():
    with open('pid','w') as f:
        f.write(str(os.getpid()))
    add_module(urls)
    server_address = ('', int(sys.argv[1]))
    httpd = HTTPServer(server_address, RequestHandler)
    logging.info('httpd4t listen on '+sys.argv[1]+'...')
    httpd.serve_forever()

if __name__=='__main__':
    run()